﻿using LCA.Community.DAL;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Linq;
using LCA.Community.DAL.Model;
using LCA.Community.DAL.Interfaces;
using System.Collections.Generic;
using LCA.Community.DAL.Test.ModelFactories;
using Microsoft.Practices.Unity;

namespace LCA.Community.DAL.Test
{
    /// <summary>
    ///This is a test class for VotesRepositoryTest and is intended
    ///to contain all VotesRepositoryTest Unit Tests
    ///</summary>
    [TestClass()]
    public class PostVotesRepositoryTest : BaseTestClass
    {
        private UsersFactory _usersFactory = new UsersFactory();
        private List<User> _users;       
        private PostsFactory _postsFactory = new PostsFactory();
        private List<Post> _posts;
        private PostVotesFactory _postVotesFactory = new PostVotesFactory();
        private List<PostVote> _votes;

        /// <summary>
        /// Initializes the test.
        /// </summary>
        [TestInitialize()]
        public void InitializeTest()
        {
            UnityContainerInitializer();

            var usersRepository = _unityContainer.Resolve<IUsersRepository>();
            _users = _usersFactory.CreateList(5);
            _users.ForEach(user => usersRepository.Add(user));

            var postRepository = _unityContainer.Resolve<IPostsRepository>();
            _posts = _postsFactory.CreateList(5,_users[0].RowKey);
            _posts.ForEach(p => postRepository.Add(p));

            _votes = new List<PostVote>();
            var postVotesRepository = _unityContainer.Resolve<IPostVotesRepository>();
            var vote = _postVotesFactory.CreateEntity(_posts[0].RowKey, _users[1].RowKey);
            postVotesRepository.Add(vote);
            _votes.Add(vote);

            vote = _postVotesFactory.CreateEntity(_posts[0].RowKey, _users[2].RowKey);
            postVotesRepository.Add(vote);
            _votes.Add(vote);

            vote = _postVotesFactory.CreateEntity(_posts[0].RowKey, _users[3].RowKey);
            postVotesRepository.Add(vote);
            _votes.Add(vote);

            vote = _postVotesFactory.CreateEntity(_posts[0].RowKey, _users[4].RowKey);
            postVotesRepository.Add(vote);
            _votes.Add(vote);
        }

        /// <summary>
        /// Cleans up the test.
        /// </summary>
        [TestCleanup()]
        public void CleanupTest()
        {
            var usersRepository = _unityContainer.Resolve<IUsersRepository>();
            var postRepository = _unityContainer.Resolve<IPostsRepository>();
            var postVotesRepository = _unityContainer.Resolve<IPostVotesRepository>();

            usersRepository.DeleteTestEntities();
            postVotesRepository.DeleteTestEntities();
            postRepository.DeleteTestEntities();
        }

        /// <summary>
        ///A test for GetPostVotesCount
        ///</summary>
        [TestMethod()]
        public void GetPostVotesCountTest()
        {
            var target = _unityContainer.Resolve<IPostVotesRepository>();
            string postID = _posts[0].RowKey;
            int expected = 4;
            int actual;

            actual = target.GetPostVotesCount(postID);
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for UserHasVotedPost
        ///</summary>
        [TestMethod()]
        public void UserHasVotedPostTest()
        {
            var target = _unityContainer.Resolve<IPostVotesRepository>();
            string userID = _users[0].RowKey;
            string postID = _posts[0].RowKey;
            bool expected = false;
            bool actual;

            actual = target.UserHasVotedPost(userID, postID);
            Assert.AreEqual(expected, actual);

            userID = _users[1].RowKey;
            expected = true;
            actual = target.UserHasVotedPost(userID, postID);
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for DeleteAllPostVotesFromPost
        ///</summary>
        [TestMethod()]
        public void DeleteAllPostVotesFromPostTest()
        {
            var target = _unityContainer.Resolve<IPostVotesRepository>();
            string postID = _posts[0].RowKey;
            target.DeleteAllPostVotesFromPost(postID);

            var actual = target.GetPostVotesByPost(postID);
            CollectionAssert.AreEquivalent(new List<PostVote>(), actual);
        }

        /// <summary>
        ///A test for GetPostVotesByPost
        ///</summary>
        [TestMethod()]
        public void GetPostVotesByPostTest()
        {
            var target = _unityContainer.Resolve<IPostVotesRepository>();
            string postID = _posts[0].RowKey;
            List<PostVote> expected = _votes;
            List<PostVote> actual;

            actual = target.GetPostVotesByPost(postID);
            CollectionAssert.AreEquivalent(expected, actual);
        }

        /// <summary>
        ///A test for DeleteAllPostVotesFromUser
        ///</summary>
        [TestMethod()]
        public void DeleteAllPostVotesFromUserTest()
        {
            var target = _unityContainer.Resolve<IPostVotesRepository>();
            string userID = _users[1].RowKey;

            target.DeleteAllPostVotesFromUser(userID);
            var actual = target.GetPostVotesByUser(userID);
            CollectionAssert.AreEquivalent(new List<PostVote>(), actual);
        }

        /// <summary>
        ///A test for GetPostVotesByUser
        ///</summary>
        [TestMethod()]
        public void GetPostVotesByUserTest()
        {
            var target = _unityContainer.Resolve<IPostVotesRepository>();
            string userID = _users[0].RowKey;
            var expected = _votes.Where(v => v.User == userID).ToList();

            var actual = target.GetPostVotesByUser(userID);
            CollectionAssert.AreEquivalent(expected, actual);
        }
    }
}
